local hotitem = { rule_exact = {}, rule_wild = {}, ver = -1 }
local cjson = require "cjson.safe"

function hotitem.parse(self, val, ver)
    if not val then
        return
    end

    if self.ver == ver then
        return
    end

    local rulelist, err = cjson.decode(val)
    if not rulelist then
        ngx.log(ngx.WARN, "hotitem: can not decode rule")
        return
    end

    local rule_exact, rule_wild = {}, {}

    for _, i in pairs(rulelist) do
        local start = string.find(i.urlPattern, '*')
        if start then
            rule_wild[#rule_wild + 1] = { type = i.type, app = i.app, uri = { string.sub(i.urlPattern, 1, start - 1), string.sub(i.urlPattern, start + 1, -1) }, id = i.idPattern }
        else
            rule_exact[#rule_exact + 1] = { type = i.type, app = i.app, uri = i.urlPattern, id = i.idPattern }
        end
    end

    local cmp = function(a, b) return string.len(a.uri) > string.len(b.uri) end

    table.sort(rule_exact, cmp)

    self.rule_exact = rule_exact
    self.rule_wild = rule_wild
    self.ver = ver

--    for _, i in pairs(self.rule_exact) do
--         ngx.log(ngx.WARN, "exact ", i.uri, " ", i.id, " ", i.app)
--    end
--
--    for _, i in pairs(self.rule_wild) do
--        ngx.log(ngx.WARN, "wild ", i.uri[1], " ", i.uri[2], " ", i.id, " ", i.app)
--    end
--
--    ngx.log(ngx.WARN, string.byte(self.ver))
end

function hotitem.filter(self, uri)
--    ngx.log(ngx.WARN, "filter ", " ", uri, " ", args, " ", #self.rule_exact, " ", #self.rule_wild, " ", string.byte(self.ver))

    if #self.rule_exact == 0 and #self.rule_wild == 0 then
        return nil
    end

    for _, i in pairs(self.rule_exact) do
        local j = string.find(uri, i.uri)
        --ngx.log(ngx.WARN, "filter exact ", uri, ", ", i.uri, ", ", j)
        if j == 1 then
            local m = ngx.req.get_uri_args()[i.id]
            --local m = ngx.re.match(args, i.id)
            if m then
                --ngx.log(ngx.WARN, "filter exact ", m, " ", i.app, i.type)
                --return item id
                if type(m) == "table" then
                    return m[1], i.app, i.type
                else
                    return m, i.app, i.type
                end
            end
            --break
        end
    end

    for _, i in pairs(self.rule_wild) do
        local j1, j2 = string.find(uri, i.uri[1]), string.find(uri, i.uri[2])
        --ngx.log(ngx.WARN, "filter wild ", j1, j2)
        if j1 == 1 and j2 then
            local m = ngx.req.get_uri_args()[i.id]
            --local m = ngx.re.match(args, i.id)
            if m then
                --ngx.log(ngx.WARN, "filter wild ", m, " ", i.app)
                --return item id
                if type(m) == "table" then
                    return m[1], i.app, i.type
                else
                    return m, i.app, i.type
                end
            end
            --return nil
        end
    end

    return nil
end

return hotitem
